<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<title>Ebtables Hacking HOWTO: Reference manual</title>
</head>
<body>
<a HREF="ebtables-hacking-HOWTO-4.html">Next</a>
<a HREF="ebtables-hacking-HOWTO-2.html">Previous</a>
<a HREF="ebtables-hacking-HOWTO.html#toc3">Contents</a>
<hr>
<h2><a NAME="s3">3.</a> <a HREF="netfilter-hacking-HOWTO.html#toc3">Reference manual</a></h2>
<p>
This section (claims that it) contains the knowledge necessary to write an extension. For a first time reader
it's probably less boring to first read the examples section and come back here when necessary.
</p>
<h2><a NAME="ss3.1">3.1</a> <a HREF="ebtables-hacking-HOWTO.html#toc3.1">Userspace</a>
</h2>
<p>
The userspace modules are responsible for putting the user's input into the right form to be given to
the kernel.
</p>
<h3><a NAME="ss3.1.1">3.1.1</a> <a HREF="ebtables-hacking-HOWTO.html#toc3.1.1">Matches</a>
</h3>
<p>
A match module is a piece of code that looks at frames passing by and decides whether that frame
matches certain conditions or not. The userspace match is contained in a
<CODE>struct ebt_u_match</CODE>, of which the fields important to the match implementor will be
described now:
<ol>
<li><CODE>char name[EBT_FUNCTION_MAXNAMELEN]<CODE>
<p>The name of the match, for example <CODE>ip</CODE>. Try to keep yourself from using capitals.</p>
</li>
<li><CODE>unsigned int size</CODE>
<p>The size of the match data, without the extra padding needed for alignment (this is added by the generic code).</p>
</li>
<li><CODE>void (*help)(void)</CODE>
<p>This function should print out the help information for the match, when the user asks for it
with the <CODE>-h &#60match&#62</CODE> command. The function can expect a '\n' to have been
printed right before it is executed and should end with at least one '\n'. The output should
explain the usage of the module and should look similar to the standard help.
</p>
</li>
<li><CODE>void (*init)(struct ebt_entry_match *m)</CODE>
<p>This function is executed when the ebtables program starts execution, before any user commands
are processed. Initializing any private data should be done at this time. The data inside the
match struct can be initialized too, using the function's argument <CODE>m</CODE>.
</p>
</li>
<li><CODE>int (*parse)(int c, char **argv, int argc,<BR>
	        const struct ebt_u_entry *entry, unsigned int *flags,<BR>
	        struct ebt_entry_match **match)<CODE>
<p>This function parses a user option given on the command line. The function can abort execution
of the program using ebtables' <CODE>print_error()</CODE> function when appropriate. The return
value for success is 1, in case of failure it is 0.<br>
<CODE>c</CODE> contains the option the user used on the command line, <CODE>argv</CODE> and <CODE>argc</CODE>
are the same two parameters given to the <CODE>main</CODE> function. <CODE>entry</CODE> points to the
complete new rule that is being constructed. <CODE>flags</CODE> points to an unsigned int private to the
module that can have any value the module wants. In practice it is used to contain flags for which options
are already processed. <CODE>match</CODE> points to the data of the match, as you can see it's a double pointer,
meaning you are allowed to change the address of the match's data (this is done f.e. in ebt_among.c).
</p>
</li>
<li><CODE>void (*final_check)(const struct ebt_u_entry *entry,<BR>
	   const struct ebt_entry_match *match,<BR>
	   const char *name, unsigned int hookmask, unsigned int time)</CODE>
<p>This function is executed after the new rule has been completely parsed without errors. Here you can see
if there is no invalid use of different options. For example, if the match only works for protocol XyZ, then
you should check that the user specified <CODE>-p XyZ</CODE>. The <CODE>name</CODE> argument contains the name
of the table the rule will be put in, <CODE>hookmask</CODE> contains the mask that describes from which base
chains the rule can be accessed. Because this function can be called twice during the execution of the
program, the value <CODE>time</CODE> equals 0 for the first execution and 1 for the second. In some situations
it is necessary to have this knowledge (see <a HREF="#ss3.1.4">section 3.1.4</a> for more information).
</p>
</li>
<li><CODE>void (*print)(const struct ebt_u_entry *entry,<BR>
	   const struct ebt_entry_match *match)</CODE>
<p>
This function is executed when the user wants to list the rules and if a rule contains this match. The output should
be in a format the user could have used to make the rule, so that the option '--Lx' stays useful.
</p>
</li>
<li><CODE>int (*compare)(const struct ebt_entry_match *m1,<BR>
	   const struct ebt_entry_match *m2)</CODE>
<p>
This function is executed when 2 rules have to be compared with each other and both contain this match. A return value
of 1 means the matches in both rules are the same, otherwise the return value must be 0.
</p>
</li>
<li><CODE>const struct option *extra_ops</CODE>
<p>
This points to a <CODE>struct option</CODE>, recognized by the library function <CODE>getopt_long</CODE>. This contains
the options the user can use for the match module. Options specific to a match should start with a specific prefix, then
a minus, then the option specifying name. For example, the IP match has an option "ip-source" for matching the IP source address.
</p>
</li>
</ol>
</p>
<h3><a NAME="ss3.1.2">3.1.2</a> <a HREF="ebtables-hacking-HOWTO.html#toc3.1.2">Watchers</a>
</h3>
<p>
A watcher module is a piece of code that looks at frames passing by, after they have passed all matches of the rule in which the
watcher is contained. A watcher only looks at a frame and will probably log something or keep statistics. Watchers are in ebtables
because it allows to have a watcher and a target in the same rule. Therefore you can log stuff with the log watcher, while still
being able to give a target. Without watchers, you would need two rules for this, which is slower and ugly.<br><br>
The userspace watcher is contained in a <CODE>struct ebt_u_watcher</CODE> that has the same relevant fields as the match, so we refer
to the previous section (mentally replace match by watcher where necessary).
</p>
<h3><a NAME="ss3.1.3">3.1.3</a> <a HREF="ebtables-hacking-HOWTO.html#toc3.1.3">Targets</a>
</h3>
<p>
A target module is a piece of code that does a certain action when all matches of a rule are passed and after the watchers in
the rule (if any) are executed.<br><br>
The userspace target is contained in a <CODE>struct ebt_u_target</CODE> that has the same relevant fields as the match, so we refer
to the first section (mentally replace match by target where necessary).
</p>
<h3><a NAME="ss3.1.4">3.1.4</a> <a HREF="ebtables-hacking-HOWTO.html#toc3.1.4">Miscellaneous</a>
</h3>
<p>
This section contains more general information that you could need.
</p>
<p>
<em>Macro's:</em>
</p>
<p>
The following macro's are defined in <CODE>include/ebtables_u.h</CODE>
<ol>
<li>
<CODE>print_bug()</CODE>
<p>
The arguments should look like arguments to <CODE>printf</CODE>, use this macro if you want to do sanity checks on your code.
</p>
</li>
<li>
<CODE>print_error()</CODE>
<p>
The arguments should look like arguments to <CODE>printf</CODE>, use this macro to tell the user she did something wrong.
A trailing '.' is added by the macro.
</p>
</li>
<li>
<CODE>print_memory()</CODE>
<p>
Use this macro when <CODE>malloc</CODE> and friends fail. No arguments allowed.
</p>
</li>
<li>
<CODE>FILL_TARGET(string, pos)</CODE>
<p>
This macro fills the integer <CODE>pos</CODE> with the value representing the target <CODE>string</CODE>. So, if you want <CODE>pos</CODE> to contain the value for RETURN,
use <CODE>FILL_TARGET("RETURN", pos);</CODE>
</p>
</li>
<li>
<CODE>TARGET_NAME(value)</CODE>
<p>
This macro produces the target string corresponding to the given target <CODE>value</CODE>. Use this to convert a stored numeric value to a string that can be printed for
the user to read.
</p>
</li>
<li>
<CODE>BASE_CHAIN</CODE>
<p>
This macro produces a boolean with value true if the rule is in a base chain. This is used for example to prevent a RETURN target on a base chain.
</p>
</li>
<li>
<CODE>CLEAR_BASE_CHAIN_BIT</CODE>
<p>
This macro should be used (only once) before using the <CODE>hookmask</CODE> in the <CODE>final_check()</CODE> function.
If you want to use <CODE>BASE_CHAIN</CODE> you must use it earlier in the function.
</p>
</li>
</ol>
</p>
<p>
<em>The <CODE>time</CODE> argument to <CODE>final_check()</CODE>:</em>
</p>
<p>
Some extra explanation about the <CODE>time</CODE> argument of the <CODE>final_check()</CODE> function is perhaps needed. When a rule is added, this rule can have as
target a user defined chain. It can be, for example, that introducing this new rule makes a certain target accessible from a base chain that is not allowed for that target.
Before this rule was added, this target was not accessible from the base chain, but after the rule was added it is.
Therefore, after an add or insert, all the <CODE>final_check()</CODE> functions of all
the modules used in all chains are called, the value of <CODE>time</CODE> will be set to 1. We could of course be lazy and let this checking up to the kernel, but it's the
policy of ebtables that any rejected table from the kernel is caused by an ebtables userspace bug. Userspace should make sure no invalid data can go to the kernel. This does
not mean that the kernel no longer has to check for validity, of course.
</p>
<p>
<em>A complete rule:</em>
</p>
<p>
The <CODE>struct ebt_u_entry</CODE> contains the information of a rule. Most module functions that are called by the base ebtables code have this struct as an argument.
However, I feel there is only one field that can be needed by the userspace module:
<ol>
<li><CODE>uint16_t ethproto</CODE>
<p>
This contains the Ethernet protocol specified by the user, its value is zero if the user did not specify a specific protocol. The value is in host endian, so there is no need
for <CODE>ntohs()</CODE>. The <CODE>final_check()</CODE> can need this value to be sure the module is used with the right specified Ethernet protocol.
</p>
</li>
</ol>
</p>
<p>
<em>Adding a new table:</em>
</p>
<p>
A module for a new table can be added too, the table's information is stored in a <CODE>struct ebt_u_table</CODE> and has following relevant members:
<ol>
<li><CODE>char name[EBT_TABLE_MAXNAMELEN]</CODE>
<p>
The name of the table. Try to keep yourself from using capital letters.
</p>
</li>
<li><CODE>void (*check)(struct ebt_u_replace *repl)</CODE>
<p>
This function gets the complete table as an argument and can do all the checks it likes. It should use <CODE>print_error()</CODE> if the table is invalid. However, there
is probably no need to make this function.
</p>
</li>
<li><CODE>void (*help)(char **)</CODE>
<p>
This function gets executed when the user gives the '-h' command, it should at least print out the supported chains for the table. You can assume a '\n' has been printed
prior to the function's execution, it should also end with at least one '\n'.
</p>
</li>
</ol>
</p>
<p>
<em>Useful functions:</em>
</p>
<p>
Now follows a description of other functions that are useful for a module.
<ol>
<li><CODE>void register_table(struct ebt_u_table *)</CODE>
<p>
Is needed in the initialization function of a table module, to register the table's data, namely the <CODE>name</CODE> and the <CODE>check</CODE> and <CODE>help</CODE> functions.
</p>
</li>
<li><CODE>void register_match(struct ebt_u_match *)</CODE>
<p>
Is needed in the initialization function of a match module, to register its data.
</p>
</li>
<li><CODE>void register_watcher(struct ebt_u_watcher *)</CODE>
<p>
Is needed in the initialization function of a watcher module, to register its data.
</p>
</li>
<li><CODE>void register_target(struct ebt_u_target *t)</CODE>
<p>
Is needed in the initialization function of a target module, to register its data.
</p>
</li>
<li><CODE>struct ethertypeent *getethertypebyname(const char *name)</CODE>
<p>
Translate a name of an Ethernet protocol to the corresponding protocol number. The
translation is done using /etc/ethertypes.
</p>
</li>
<li><CODE>struct ethertypeent *getethertypebynumber(int type)</CODE>
<p>
Translate a protocol number to a protocol name, using /etc/ethertypes.
</p>
</li>
<li><CODE>void check_option(unsigned int *flags, unsigned int mask)</CODE>
<p>
Checks the boolean <CODE>(*flags & mask)</CODE>. Normally, <CODE>mask</CODE> should be a power of 2 and <CODE>flags</CODE> points to an integer containing
all the options already processed for the specific module. If the boolean is true then an error message is printed to the screen about double usage
of the same option and the program exits. If the boolean is false, the bit in <CODE>*flags</CODE> for the specific option is put to 1.
</p>
</li>
<li><CODE>int check_inverse(const char option[])</CODE>
<p>
Checks if the string argument equals "!". If it does, <CODE>optind</CODE> is increased and 1 is returned, else 0 is returned. As this function can increase <CODE>optind</CODE>,
the code that comes behind the call to this function has to use <CODE>argv[optind - 1]</CODE>, not <CODE>optarg</CODE> because <CODE>optarg</CODE> can point to the "!".
</p>
</li>
</ol>
</p>
<p>
<em>The <CODE>hookmask</CODE> argument to <CODE>final_check()</CODE>:</em>
</p>
<p>
The usage of the <CODE>hookmask</CODE> argument for the <CODE>final_check()</CODE> function could use some extra explaining. This mask contains the information from which
base chain the rule in question (so the module's data in question) can be reached. If your module is only viable for certain base chains, you should check it isn't used
in an invalid chain. If the rule can be reached through the PREROUTING chain, then the NF_BR_PRE_ROUTING'th least significant bit will be set for <CODE>hookmask</CODE>. Here
is a list of all constants: NF_BR_PRE_ROUTING = 0, NF_BR_LOCAL_IN = 1, NF_BR_FORWARD = 2, NF_BR_LOCAL_OUT = 3, NF_BR_POST_ROUTING = 4, NF_BR_BROUTING = 5. See the already
implemented modules for examples.
</p>
<h2><a NAME="ss3.2">3.2</a> <a HREF="ebtables-hacking-HOWTO.html#toc3.2">Kernel</a>
</h2>
<p>
The kernel modules are responsible for checking the data received by userspace and its main task is doing whatever the
data tells the module to do, with a frame.
</p>
<h3><a NAME="ss3.2.1">3.2.1</a> <a HREF="ebtables-hacking-HOWTO.html#toc3.2.1">Matches</a>
</h3>
<p>
The kernel match module is contained in a <CODE>struct ebt_match</CODE> of which its relevant fields will be discussed now:
<ol>
<li><CODE>char name[EBT_FUNCTION_MAXNAMELEN]</CODE>
<p>
The name of the match, should be the same as the name of the corresponding userspace match.
</p></li>
<li><CODE>int (*match)(const struct sk_buff *skb, const struct net_device *in,<BR>
                       const struct net_device *out, const void *matchdata,<BR>
                       unsigned int datalen)</CODE>
<p>
Checks if the frame (<CODE>skb</CODE>) matches the data from the match (<CODE>matchdata</CODE>) contained in the rule. If it matches,
EBT_MATCH (=0) is returned, else EBT_NOMATCH (=1) is returned. This function is executed for every frame that
comes into contact with a rule utilizing the match in question.
</p></li>
<li><CODE>int (*check)(const char *tablename, unsigned int hookmask,<BR>
                       const struct ebt_entry *e, void *matchdata, unsigned int datalen)</CODE>
<p>
Checks the data of the match (<CODE>matchdata</CODE>) contained in the rule (<CODE>e</CODE>) to see if it is valid. This function is executed
when the user gives new table data to the kernel. Returns 0 on success, a negative value (e.g. <CODE>-EINVAL</CODE>) on failure.
</p></li>
<li><CODE>void (*destroy)(void *matchdata, unsigned int datalen)</CODE>
<p>
Contains the code executed when a rule utilizing the match is removed. Set to <CODE>NULL</CODE> if not used.
</p></li>
<li><CODE>struct module *me</CODE>
<p>
Always set to <CODE>THIS_MODULE</CODE>.
</p>
</li>
</ol>
</p>
<h3><a NAME="ss3.2.2">3.2.2</a> <a HREF="ebtables-hacking-HOWTO.html#toc3.2.2">Watchers</a>
</h3>
<p>
The watchers are contained in a <CODE>struct ebt_watcher</CODE>, its members are basically the same as
for the <CODE>struct ebt_match</CODE>, except that the <CODE>watcher()</CODE> function
(which is analogous to the <CODE>match()</CODE> function) has no return value.
</p>
<h3><a NAME="ss3.2.3">3.2.3</a> <a HREF="ebtables-hacking-HOWTO.html#toc3.2.3">Targets</a>
</h3>
<p>
The targets are contained in a <CODE>struct ebt_target</CODE>, its members are basically the same as
for the <CODE>struct ebt_match</CODE>, except that it contains a <CODE>target()</CODE> member instead of a <CODE>match()</CODE> member.
This <CODE>target()</CODE> function gives back a basic decision to the main ebtables
code. This decision is <CODE>EBT_ACCEPT</CODE>, <CODE>EBT_DROP</CODE>, <CODE>EBT_CONTINUE</CODE> or <CODE>EBT_RETURN</CODE>.
The <CODE>target()</CODE> function should make sure the decision cannot be <CODE>EBT_RETURN</CODE> for a rule on a base chain.
</p>
<h3><a NAME="ss3.2.4">3.2.4</a> <a HREF="ebtables-hacking-HOWTO.html#toc3.2.4">Miscellaneous</a>
</h3>
<p>
<em>Macros:</em>
</p>
<p>
Some macros useful to ebtables kernel modules:
<ol>
<li><CODE>FWINV(bool,invflg)</CODE>
<p>
Used in the <CODE>match()</CODE> functions. The <CODE>bool</CODE> argument contains some boolean expression
and the <CODE>invflg</CODE> argument has the bit set for a specific option. See the implementation in <CODE>ebtables.h</CODE> and
the usage in f.e. <CODE>ebt_ip.c</CODE> for more details.
</p>
</li>
<li>
<CODE>BASE_CHAIN</CODE>
<p>
True if the hook mask denotes that the rule is in a base chain,
used in the <CODE>check()</CODE> functions.
</p>
</li>
<li><CODE>CLEAR_BASE_CHAIN_BIT</CODE>
<p>
This macro should be used (only once) before using the <CODE>hookmask</CODE> in the <CODE>check()</CODE> function.
If you want to use <CODE>BASE_CHAIN</CODE> you must use it earlier in the function.
See f.e. <CODE>ebt_dnat.c</CODE>.
</p>
</li>
<li><CODE>INVALID_TARGET</CODE>
<p>
True if the target (an integer) is not a standard target. See f.e. <CODE>ebt_dnat.c</CODE> for its usage.
</p>
</li>
</ol>
</p>
<p>
<em>Adding a new table:</em>
</p>
<p>
You can also make a new table, see the existing implementations (e.g. <CODE>ebtable_filter.c</CODE>) for details.
</p>
<p>
<em>Useful functions:</em>
</p>
<p>
<ol>
<li><CODE>int ebt_register_table(struct ebt_table *table)</CODE>
<p>
Registers the table with its data contained in the <CODE>struct ebt_table *table</CODE>. Returns a negative value on failure.
This is used in the initialization function of a table module.
</p>
</li>
<li><CODE>void ebt_unregister_table(struct ebt_table *table)</CODE>
<p>
Unregisters the table. This is used in the function that is called when the module is unloaded and also when something goes wrong
in the initialization function.
</p>
</li>
<li><CODE>int ebt_register_match(struct ebt_match *match)</CODE>
<p>
Registers the match with its data contained in the <CODE>struct ebt_match *match</CODE>. Returns a negative value on failure.
This is used in the initialization function of a match module.
</p>
</li>
<li><CODE>void ebt_unregister_match(struct ebt_match *match)</CODE>
<p>
Unregisters the match. This is used in the function that is called when the module is unloaded and also when something goes wrong
in the initialization function.
</p>
</li>
<li><CODE>int ebt_register_watcher(struct ebt_watcher *watcher)</CODE>
<p>
Registers the watcher with its data contained in the <CODE>struct ebt_watcher *watcher</CODE>. Returns a negative value on failure.
This is used in the initialization function of a watcher module.
</p>
</li>
<li><CODE>void ebt_unregister_watcher(struct ebt_watcher *watcher)</CODE>
<p>
Unregisters the watcher. This is used in the function that is called when the module is unloaded and also when something goes wrong
in the initialization function.
</p>
</li>
<li><CODE>int ebt_register_target(struct ebt_target *target)</CODE>
<p>
Registers the target with its data contained in the <CODE>struct ebt_target *target</CODE>. Returns a negative value on failure.
This is used in the initialization function of a target module.
</p>
</li>
<li><CODE>void ebt_unregister_target(struct ebt_target *target)</CODE>
<p>
Unregisters the target. This is used in the function that is called when the module is unloaded and also when something goes wrong
in the initialization function.
</p>
</li>
</ol>
</p>
<h2><a NAME="ss3.3">3.3</a> <a HREF="ebtables-hacking-HOWTO.html#toc3.3">General rules</a>
</h2>
<p>
<ol>
<li>
Indentation should be done using tabs.
</li>
<li>
No more than 80 columns should be used, taking into account tab width of 8 characters.
</li>
<li>
Bad or corrupt data should never be accepted by the kernel module's <CODE>check()</CODE> function. The userspace module should be
built so that no bad or corrupt data can ever be given to the kernel. If the kernel does not accept data given to it, this is considered
a userspace bug.
</li>
</ol>
</p>
<hr>
<a HREF="ebtables-hacking-HOWTO-4.html">Next</a>
<a HREF="ebtables-hacking-HOWTO-2.html">Previous</a>
<a HREF="ebtables-hacking-HOWTO.html#toc3">Contents</a>
</body>
</html>
